home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / comms / b_link10.zip / B-LINK.EXE / B-LINK / B-LINK.BAS next >
BASIC Source File  |  1994-02-06  |  56KB  |  1,989 lines

  1. '
  2. '
  3. '
  4. '
  5. '
  6. '
  7. ' B-LINK - BASIC Link to the NEWTON
  8. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  9. '
  10. '
  11. '
  12. ' This program may be freely distributed provided it is not altered and
  13. ' no fees may be charged for it's distribution.
  14. '
  15. '
  16. '
  17. '
  18. '
  19. '
  20. '
  21. 'Sub and function declarations
  22. DECLARE SUB showdump (dinp$, dLEN%)
  23. DECLARE SUB Summary ()
  24. DECLARE SUB LCenter (text$)
  25. DECLARE SUB Initialize ()
  26. DECLARE SUB Intro ()
  27. DECLARE SUB SparklePause ()
  28. DECLARE SUB center (row%, text$)
  29. DECLARE SUB FancyCls (dots%, Background%)
  30. DECLARE SUB MenuSystem ()
  31. DECLARE SUB Box (Row1%, Col1%, Row2%, Col2%)
  32. DECLARE SUB PrintHelpLine (Help$)
  33. DECLARE SUB DataEntry ()
  34. DECLARE SUB Summary ()
  35. DECLARE SUB InitSF ()
  36. DECLARE SUB ShowMessage (message$)
  37. DECLARE SUB ClearMessage ()
  38. DECLARE SUB LoadRecords ()
  39. DECLARE SUB SaveRecords ()
  40. DECLARE SUB ClearFields ()
  41. DECLARE SUB KbdEdit (buffer$, maxlen%, fg%, bg%, cancel%, edit$)
  42. DECLARE SUB AddRecord ()
  43. DECLARE SUB DeleteRecord ()
  44. DECLARE SUB EditRecord ()
  45. DECLARE SUB SortRecords ()
  46. DECLARE SUB FindRecord ()
  47. DECLARE SUB PrevRecord ()
  48. DECLARE SUB NextRecord ()
  49. DECLARE SUB PrintRecords ()
  50. DECLARE SUB ErrBeep ()
  51. DECLARE SUB Help ()
  52. DECLARE SUB ShowRecord ()
  53. DECLARE SUB PaintDisplay ()
  54. DECLARE SUB Frame (top%, bottom%, left%, right%)
  55.  
  56. DECLARE FUNCTION CompareRecords% (index1%, index2%)
  57. DECLARE FUNCTION GetYesNo% (prompt$)
  58. DECLARE FUNCTION GetKey$ ()
  59. DECLARE FUNCTION ComposeChkSum$ (chksum%)
  60. DECLARE FUNCTION checksum% (inbuff$)
  61. DECLARE FUNCTION XmitNewton% ()
  62. DECLARE FUNCTION GetString$ (row%, col%, start$, end$, Vis%, Max%)
  63. DECLARE FUNCTION Trim$ (x$)
  64. DECLARE FUNCTION CheckEdit% (temp$, edit$)
  65. DECLARE FUNCTION Menu% (CurrChoiceX%, MaxChoice%, choice$(), ItemRow%(), ItemCol%(), menuHelp$(), BarMode%)
  66.  
  67. DEFINT A-Z
  68.  
  69. 'Constants
  70. CONST TRUE = -1
  71. CONST FALSE = NOT TRUE
  72.  
  73. CONST NNAMES = 1
  74. CONST NSCHED = 2
  75. CONST NANN = 3
  76. CONST NDAILY = 4
  77. CONST NALARM = 5
  78. CONST NNOTE = 6
  79.  
  80. 'Makes arrays dynamic
  81. '$DYNAMIC
  82.  
  83. CONST WINTOP = 5, WINBOTTOM = 19
  84. CONST WINLEFT = 10, WINRIGHT = 70
  85.  
  86. CONST MESSAGEROW = 22
  87.  
  88. TYPE CRrecord
  89.         CRType AS INTEGER
  90.         CRData AS STRING * 255
  91. END TYPE
  92.  
  93. TYPE SFField
  94.         SFScreen AS INTEGER
  95.         SFName AS STRING * 25
  96.         SFMax AS INTEGER
  97.         SFRow AS INTEGER
  98.         SFCol AS INTEGER
  99.         SFData AS STRING * 255
  100.         SFedit AS STRING * 1
  101.         SFPos AS INTEGER
  102.         SFSuff AS INTEGER
  103. END TYPE
  104.        
  105. TYPE ScreenD
  106.         fieldptr AS INTEGER
  107.         fname AS STRING * 40
  108. END TYPE
  109.  
  110. TYPE Sharp
  111.         Sname AS STRING * 13
  112.         Sapp  AS STRING * 11
  113.         Snum  AS STRING * 4
  114.         Schksum AS DOUBLE
  115.         Sfields AS INTEGER
  116. END TYPE
  117.  
  118. COMMON SHARED scrnFg
  119. COMMON SHARED scrnBg
  120. COMMON SHARED winFg
  121. COMMON SHARED winBg
  122. COMMON SHARED statFg
  123. COMMON SHARED statBg
  124.  
  125. COMMON SHARED NumRecords
  126. COMMON SHARED CurrRecord
  127.  
  128. COMMON SHARED EditState$
  129.  
  130. COMMON SHARED SFScreenNum
  131.  
  132. COMMON SHARED CRLF$
  133. COMMON SHARED ETX$
  134. COMMON SHARED SUB$
  135. COMMON SHARED HT$
  136.  
  137. COMMON SHARED COMM$
  138.  
  139. 'Global variables
  140. DIM SHARED ColorPref                            'Color Preference
  141. DIM SHARED colors(0 TO 20, 1 TO 4)              'Different Colors
  142. DIM SHARED PrintErr AS INTEGER                  'Printer error flag
  143. DIM SHARED CRrecords(0) AS CRrecord
  144. DIM SHARED fields(30) AS SFField
  145. DIM SHARED ScreenData(6) AS ScreenD
  146. DIM SHARED SharpRec(6) AS Sharp
  147.  
  148.     DEF SEG = 0                     ' Turn off CapLock, NumLock and ScrollLock
  149.     KeyFlags = PEEK(1047)
  150.     POKE 1047, &H0
  151.     DEF SEG
  152.  
  153.    NumRecords = 0
  154.    CurrRecord = 0
  155.  
  156.     scrnFg = 11
  157.     scrnBg = 1
  158.     winFg = 0
  159.     winBg = 7
  160.     statFg = 0
  161.     statBg = 3
  162.  
  163.     Initialize          'Initialize program
  164.     CALL InitSF         'Init fields
  165.     Intro               'Display introduction screen
  166.     MenuSystem          'This is the main program
  167.     COLOR 7, 0          'Clear screen and end
  168.     CLS
  169.  
  170.     DEF SEG = 0                     ' Restore CapLock, NumLock and ScrollLock states
  171.     POKE 1047, KeyFlags
  172.     DEF SEG
  173.  
  174.     SYSTEM
  175.     END
  176.  
  177.  
  178. 'The following data defines the color schemes available via the main menu.
  179. '                            0 0 14 14  
  180. '    scrn  dots  bar  back   title  shdow  choice  curs   cursbk  shdow
  181. DATA 0,    7,    15,  7,     0,     7,     0,      15,    0,      0
  182. DATA 1,    9,    12,  3,     0,     1,     15,     0,     7,      0
  183. DATA 3,    15,   13,  1,     0,     3,     15,     0,     7,      0
  184. DATA 7,    12,   15,  4,     0,     0,     15,     15,    1,      0
  185.  
  186. REM $STATIC
  187. ' B-LINK - BASIC Link to the NEWTON
  188. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  189. '
  190. ' This program may be freely distributed provided it is not altered and
  191. ' no fees may be charged for it's distribution.
  192. '
  193. '
  194. ' Adds a new record to the database and makes it the current record
  195. '
  196. SUB AddRecord
  197.  
  198.    DIM newentry AS CRrecord        'Temporary record
  199.  
  200.    COLOR winFg, winBg
  201.    CALL ClearFields              'Clear current record from window
  202.  
  203.         i = ScreenData(SFScreenNum).fieldptr
  204.         recpos = 1
  205.         DO WHILE fields(i).SFScreen = SFScreenNum
  206.                 LOCATE fields(i).SFRow, fields(i).SFCol
  207.                 tempfield$ = SPACE$(fields(i).SFMax)
  208.                 CALL KbdEdit(tempfield$, fields(i).SFMax, winFg, winBg, cancel, fields(i).SFedit)
  209.                 IF cancel THEN GOTO cancelEntry
  210.                 ' put the update into newentry's data field
  211.                 MID$(newentry.CRData, recpos, fields(i).SFMax) = LEFT$(tempfield$, fields(i).SFMax)
  212.                 recpos = recpos + fields(i).SFMax
  213.                 i = i + 1
  214.                 LOOP
  215.  
  216.    'Allocate temporary storage for records
  217.    REDIM temp(NumRecords) AS CRrecord
  218.    FOR i = 1 TO NumRecords
  219.       temp(i) = CRrecords(i)
  220.    NEXT i
  221.  
  222.    'Resize records array and restore records
  223.    REDIM CRrecords(NumRecords + 1) AS CRrecord
  224.    FOR i = 1 TO NumRecords
  225.       CRrecords(i) = temp(i)
  226.    NEXT i
  227.    ERASE temp
  228.  
  229.    NumRecords = NumRecords + 1
  230.    CurrRecord = NumRecords
  231.   
  232.    newentry.CRType = SFScreenNum
  233.    CRrecords(CurrRecord) = newentry
  234.  
  235. cancelEntry:
  236.    CALL ShowRecord               'Update display
  237.  
  238. END SUB
  239.  
  240. REM $DYNAMIC
  241. 'Box:
  242. '  Draw a box on the screen between the given coordinates.
  243. SUB Box (Row1, Col1, Row2, Col2) STATIC
  244.  
  245.     BoxWidth = Col2 - Col1 + 1
  246.  
  247.     LOCATE Row1, Col1
  248.     PRINT "┌"; STRING$(BoxWidth - 2, "─"); "┐";
  249.  
  250.     FOR a = Row1 + 1 TO Row2 - 1
  251.         LOCATE a, Col1
  252.         PRINT "│"; SPACE$(BoxWidth - 2); "│";
  253.     NEXT a
  254.  
  255.     LOCATE Row2, Col1
  256.     PRINT "└"; STRING$(BoxWidth - 2, "─"); "┘";
  257.  
  258. END SUB
  259.  
  260. 'Center:
  261. '  Center text on the given row.
  262. SUB center (row, text$)
  263.     LOCATE row, 41 - LEN(text$) / 2
  264.     PRINT text$;
  265. END SUB
  266.  
  267. REM $STATIC
  268. FUNCTION CheckEdit (temp$, edit$)
  269.         ret = 1
  270.         SELECT CASE edit$
  271.         CASE "Y"
  272.                 IF VAL(temp$) < 1904 OR VAL(temp$) > 2999 THEN ret = 0
  273.         CASE "M"
  274.                 IF LEN(temp$) < 4 THEN ret = 0
  275.                 mm = VAL(LEFT$(temp$, 2)): dd = VAL(RIGHT$(temp$, 2))
  276.                 IF mm < 1 OR mm > 12 OR dd < 1 OR dd > 31 THEN ret = 0
  277.         CASE "T"
  278.                 IF LEN(temp$) < 4 THEN ret = 0
  279.                 hh = VAL(LEFT$(temp$, 2)): mm = VAL(RIGHT$(temp$, 2))
  280.                 IF hh > 23 OR mm > 59 THEN ret = 0
  281.         CASE " "
  282.                 IF LEN(temp$) < 2 THEN ret = 0
  283.         END SELECT
  284.         CheckEdit = ret
  285. END FUNCTION
  286.  
  287. FUNCTION checksum% (inbuff$)
  288.         chksum = 0
  289.         FOR i = 1 TO LEN(inbuff$)
  290.                 chksum = chksum + ASC(MID$(inbuff$, i, 1))
  291.                 NEXT i
  292.         checksum = chksum
  293. END FUNCTION
  294.  
  295. '
  296. ' Clears all record fields using the current color
  297. '
  298. SUB ClearFields
  299.  
  300.         i = ScreenData(SFScreenNum).fieldptr
  301.         DO WHILE fields(i).SFScreen = SFScreenNum
  302.                 LOCATE fields(i).SFRow, fields(i).SFCol
  303.                 PRINT SPACE$(fields(i).SFMax)
  304.                 i = i + 1
  305.                 LOOP
  306.    
  307. END SUB
  308.  
  309. '
  310. ' Clears the current message from the message area
  311. '
  312. SUB ClearMessage
  313.  
  314.    COLOR scrnFg, scrnBg
  315.    LOCATE MESSAGEROW, 1
  316.    PRINT SPACE$(80)
  317.  
  318. END SUB
  319.  
  320. '
  321. ' Compares two records. Returns 1 if the first record should
  322. ' come after the second. Otherwise 0 is returned.
  323. '
  324. FUNCTION CompareRecords (index1, index2)
  325.  
  326.    CompareRecords = 0
  327.   
  328.    IF CRrecords(index1).CRType > CRrecords(index2).CRType THEN
  329.       CompareRecords = 1
  330.    ELSEIF CRrecords(index1).CRType = CRrecords(index2).CRType THEN
  331.       IF CRrecords(index1).CRType > CRrecords(index2).CRType THEN
  332.          CompareRecords = 1
  333.       END IF
  334.    END IF
  335.  
  336. END FUNCTION
  337.  
  338. FUNCTION ComposeChkSum$ (chksum)
  339.         i = chksum AND &HFF
  340.         j = INT(chksum / 256) AND &HFF
  341.         chksum$ = RIGHT$(HEX$(i + 512), 2) + RIGHT$(HEX$(j + 512), 2)
  342.         ComposeChkSum$ = chksum$
  343. END FUNCTION
  344.  
  345. ' B-LINK - BASIC Link to the NEWTON
  346. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  347. '
  348. ' This program may be freely distributed provided it is not altered and
  349. ' no fees may be charged for it's distribution.
  350. '
  351. '
  352. SUB DataEntry
  353.  
  354.    CALL PaintDisplay
  355.  
  356.    FOR i = 1 TO NumRecords
  357.         IF CRrecords(i).CRType = SFScreenNum THEN CurrRecord = i: GOTO foundrec
  358.         NEXT i
  359.    CALL AddRecord
  360.  
  361. foundrec:
  362.    CALL ShowRecord
  363.  
  364.    DO
  365.       EditState$ = " "
  366.       SELECT CASE GetKey$
  367.          CASE CHR$(&H0) + CHR$(&H3B)   'F1 (Help)
  368.             CALL Help
  369.          CASE CHR$(&H0) + CHR$(&H3C)   'F2 (Add)
  370.             CALL AddRecord
  371.          CASE CHR$(&H0) + CHR$(&H3D)   'F3 (Delete)
  372.            IF NumRecords > 0 THEN
  373.                 IF GetYesNo("Delete the current record [Y/N]?") THEN CALL DeleteRecord
  374.            ELSE
  375.                 CALL ErrBeep
  376.            END IF
  377.          CASE CHR$(&H0) + CHR$(&H3E)   'F4 (Edit)
  378.             EditState$ = "E"
  379.             CALL EditRecord
  380.          CASE CHR$(&H0) + CHR$(&H3F)   'F5 (Find)
  381.             CALL FindRecord
  382.          CASE CHR$(&H0) + CHR$(&H40)   'F6 (Previous)
  383.             CALL PrevRecord
  384.          CASE CHR$(&H0) + CHR$(&H41)   'F7 (Next)
  385.             CALL NextRecord
  386.          CASE CHR$(&H0) + CHR$(&H42)   'F8 (Send)
  387.             IF XmitNewton = -1 THEN EXIT DO
  388.          CASE CHR$(&H0) + CHR$(&H43)   'F9 (Print)
  389.             CALL PrintRecords
  390.          CASE CHR$(&H0) + CHR$(&H44)   'F10 (Exit)
  391.             EXIT DO
  392.          CASE ELSE
  393.             CALL ErrBeep
  394.       END SELECT
  395.    LOOP
  396.  
  397.    COLOR 7, 0, 0
  398.    CLS
  399.  
  400. END SUB
  401.  
  402. '
  403. ' Deletes the current record
  404. '
  405. SUB DeleteRecord
  406.  
  407.          'Allocate temporary storage for records
  408.          REDIM temp(NumRecords - 1) AS CRrecord
  409.         
  410.          'Fill temporary array with all records except
  411.          'the current record
  412.          FOR i = 1 TO (CurrRecord - 1)
  413.             temp(i) = CRrecords(i)
  414.          NEXT i
  415.          FOR i = CurrRecord TO (NumRecords - 1)
  416.             temp(i) = CRrecords(i + 1)
  417.          NEXT i
  418.  
  419.          'One less record
  420.          NumRecords = NumRecords - 1
  421.  
  422.          'Resize records array and restore records
  423.          REDIM CRrecords(NumRecords) AS CRrecord
  424.          FOR i = 1 TO NumRecords
  425.             CRrecords(i) = temp(i)
  426.          NEXT i
  427.          ERASE temp
  428.  
  429.          'Make sure currRecord remains within range
  430.          IF CurrRecord > NumRecords THEN CurrRecord = NumRecords
  431.         
  432.          CALL ShowRecord      'Update display
  433.  
  434. END SUB
  435.  
  436. ' B-LINK - BASIC Link to the NEWTON
  437. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  438. '
  439. ' This program may be freely distributed provided it is not altered and
  440. ' no fees may be charged for it's distribution.
  441. '
  442. '
  443. ' Allows the user to edit the current record
  444. '
  445. SUB EditRecord
  446.  
  447.    DIM newentry AS CRrecord        'Temporary record
  448.  
  449.    IF CurrRecord = 0 THEN        'Nothing to edit
  450.       CALL ErrBeep
  451.       EXIT SUB
  452.    END IF
  453.  
  454.    CALL ShowMessage("Edit the current field  <Enter>=Next field  <Esc>=Cancel")
  455.  
  456.    newentry = CRrecords(CurrRecord)
  457.  
  458.    COLOR statFg, statBg          'Edit record a field at a time
  459.  
  460.         i = ScreenData(SFScreenNum).fieldptr
  461.         recpos = 1
  462.         DO WHILE fields(i).SFScreen = SFScreenNum
  463.                 LOCATE fields(i).SFRow, fields(i).SFCol
  464.                 tempfield$ = fields(i).SFData
  465.                 CALL KbdEdit(tempfield$, fields(i).SFMax, winFg, winBg, cancel, fields(i).SFedit)
  466.                 IF cancel THEN GOTO cancelEdit
  467.                 ' put the update into newentry's data field
  468.                 MID$(newentry.CRData, recpos, fields(i).SFMax) = LEFT$(tempfield$, fields(i).SFMax)
  469.                 recpos = recpos + fields(i).SFMax
  470.                 i = i + 1
  471.                 LOOP
  472.        
  473.         CRrecords(CurrRecord) = newentry
  474.  
  475. cancelEdit:
  476.    CALL ShowRecord               'Update display
  477.    CALL ClearMessage
  478.  
  479. END SUB
  480.  
  481. '
  482. ' Sounds the computers internal speaker
  483. '
  484. SUB ErrBeep
  485.  
  486.    SOUND 800, 2
  487.    SOUND 400, 2
  488.   
  489.    WHILE INKEY$ <> "": WEND         'Flush keyboard buffer
  490.  
  491. END SUB
  492.  
  493. REM $DYNAMIC
  494. '  Clears screen in the right color, and draws nice dots.
  495. SUB FancyCls (dots, Background)
  496.  
  497.     VIEW PRINT 2 TO 24
  498.     COLOR dots, Background
  499.     CLS 2
  500.     VIEW PRINT
  501.  
  502. END SUB
  503.  
  504. REM $STATIC
  505. '
  506. ' Searches the database for a given string (not case sensitive)
  507. '
  508. SUB FindRecord
  509.  
  510.    'Get input and convert to upper case
  511.    LOCATE MESSAGEROW, 15
  512.    COLOR scrnFg, scrnBg
  513.    PRINT "Enter search string: ";
  514.    CALL KbdEdit(inputString$, 30, scrnFg, scrnBg, cancel, " ")
  515.    CALL ClearMessage
  516.  
  517.    IF cancel = 1 THEN EXIT SUB
  518.    searchString$ = UCASE$(inputString$)
  519.  
  520.    'Scan records for match
  521.    FOR i = 1 TO NumRecords
  522.       found = 0
  523.       IF INSTR(UCASE$(CRrecords(i).CRData), searchString$) <> 0 THEN
  524.          SFScreenNum = CRrecords(i).CRType
  525.          found = 1
  526.       END IF
  527.  
  528.       'If a match was found, show matching record and
  529.       'ask if the search should continue
  530.       IF found = 1 THEN
  531.          CurrRecord = i
  532.          CALL PaintDisplay
  533.          CALL ShowRecord
  534.          IF GetYesNo("Find next match [Y/N]?") = 0 THEN EXIT SUB
  535.       END IF
  536.    NEXT i
  537.  
  538.    'Tell user no more matches found
  539.    a$ = "Match not found for " + CHR$(&H22) + inputString$
  540.    a$ = a$ + CHR$(&H22) + ", press any key"
  541.    CALL ShowMessage(a$)
  542.    a$ = GetKey$
  543.    CALL ClearMessage
  544.  
  545. END SUB
  546.  
  547. '
  548. ' Displays a box with the specified coordinates
  549. ' The inside of the box is cleared to the current color
  550. '
  551. SUB Frame (top, bottom, left, right)
  552.  
  553.    LOCATE top, left
  554.    PRINT CHR$(&HC9); STRING$((right - left) - 1, CHR$(&HCD)); CHR$(&HBB);
  555.   
  556.    FOR row = (top + 1) TO (bottom - 1)
  557.       LOCATE row, left
  558.       PRINT CHR$(&HBA); SPACE$((right - left) - 1); CHR$(&HBA);
  559.    NEXT row
  560.  
  561.    LOCATE bottom, left
  562.    PRINT CHR$(&HC8); STRING$((right - left) - 1, CHR$(&HCD)); CHR$(&HBC);
  563.  
  564. END SUB
  565.  
  566. '
  567. ' Returns the next available keystroke (read with INKEY$)
  568. '
  569. FUNCTION GetKey$
  570.  
  571.    ch$ = "": WHILE ch$ = "": ch$ = INKEY$: WEND
  572.    GetKey$ = ch$
  573.  
  574. END FUNCTION
  575.  
  576. REM $DYNAMIC
  577. 'GetString$:
  578. '  Given a row and col, and an initial string, edit a string
  579. '  VIS is the length of the visible field of entry
  580. '  MAX is the maximum number of characters allowed in the string
  581. FUNCTION GetString$ (row, col, start$, end$, Vis, Max)
  582.     curr$ = Trim$(LEFT$(start$, Max))
  583.     IF curr$ = CHR$(8) THEN curr$ = ""
  584.  
  585.     LOCATE , , 1
  586.  
  587.     finished = FALSE
  588.     DO
  589.         GOSUB GetStringShowText
  590.         GOSUB GetStringGetKey
  591.  
  592.         IF LEN(Kbd$) > 1 THEN
  593.             finished = TRUE
  594.             GetString$ = Kbd$
  595.         ELSE
  596.             SELECT CASE Kbd$
  597.                 CASE CHR$(13), CHR$(27), CHR$(9)
  598.                     finished = TRUE
  599.                     GetString$ = Kbd$
  600.                 
  601.                 CASE CHR$(8)
  602.                     IF curr$ <> "" THEN
  603.                         curr$ = LEFT$(curr$, LEN(curr$) - 1)
  604.                     END IF
  605.  
  606.                 CASE " " TO "}"
  607.                     IF LEN(curr$) < Max THEN
  608.                         curr$ = curr$ + Kbd$
  609.                     ELSE
  610.                         BEEP
  611.                     END IF
  612.  
  613.                 CASE ELSE
  614.                     BEEP
  615.             END SELECT
  616.         END IF
  617.  
  618.     LOOP UNTIL finished
  619.  
  620.     end$ = curr$
  621.     LOCATE , , 0
  622.     EXIT FUNCTION
  623.     
  624.  
  625. GetStringShowText:
  626.     LOCATE row, col
  627.     IF LEN(curr$) > Vis THEN
  628.         PRINT RIGHT$(curr$, Vis);
  629.     ELSE
  630.         PRINT curr$; SPACE$(Vis - LEN(curr$));
  631.         LOCATE row, col + LEN(curr$)
  632.     END IF
  633.     RETURN
  634.  
  635. GetStringGetKey:
  636.     Kbd$ = ""
  637.     WHILE Kbd$ = ""
  638.         Kbd$ = INKEY$
  639.     WEND
  640.     RETURN
  641. END FUNCTION
  642.  
  643. REM $STATIC
  644. '
  645. ' Displays the given prompt and gets a yes/no response from the user
  646. ' Returns 1 if "Y" was pressed or 0 if "N" was pressed
  647. '
  648. FUNCTION GetYesNo (prompt$)
  649.  
  650.    CALL ShowMessage(prompt$)
  651.  
  652.    DO
  653.       a$ = UCASE$(GetKey$)             'Wait for "Y" or "N"
  654.       IF a$ = "Y" OR a$ = "N" THEN
  655.          EXIT DO
  656.       ELSE
  657.          CALL ErrBeep
  658.       END IF
  659.    LOOP
  660.  
  661.    CALL ClearMessage
  662.  
  663.    IF a$ = "Y" THEN GetYesNo = 1 ELSE GetYesNo = 0
  664.  
  665. END FUNCTION
  666.  
  667. '
  668. ' Displays help screen
  669. '
  670. SUB Help
  671.  
  672.    COLOR winFg, winBg
  673.    CALL Frame(5, 19, 3, 78)   'Create help window
  674.  
  675.    LOCATE 7, 33               'Display help info
  676.    PRINT "Help Screen"
  677.  
  678.    tab1 = 7
  679.    tab2 = 44
  680.    LOCATE 9, tab1
  681.    PRINT "<F1>=Help (this screen)";
  682.    LOCATE , tab2
  683.    PRINT "<F2>=Add a new record"
  684.    LOCATE , tab1
  685.    PRINT "<F3>=Delete the current record";
  686.    LOCATE , tab2
  687.    PRINT "<F4>=Edit the current record"
  688.    LOCATE , tab1
  689.    PRINT "<F5>=Find records";
  690.    LOCATE , tab2
  691.    PRINT "<F6>=Show the previous record"
  692.    LOCATE , tab1
  693.    PRINT "<F7>=Show the next record";
  694.    LOCATE , tab2
  695.    PRINT "<F8>=Send record to the NEWTON"
  696.    LOCATE , tab1
  697.    PRINT "<F9>=Send records to a printer";
  698.    LOCATE , tab2
  699.    PRINT "<F10>=Exit Data Entry"
  700.  
  701.    LOCATE 17, 27
  702.    PRINT "Press any key to exit help"
  703.    a$ = GetKey$
  704.  
  705.    CALL PaintDisplay          'Restore screen
  706.  
  707. END SUB
  708.  
  709. REM $DYNAMIC
  710. 'Initialize:
  711. ' Read colors in
  712. SUB Initialize
  713.  
  714.     WIDTH , 25
  715.     VIEW PRINT
  716.  
  717.     FOR ColorSet = 1 TO 4
  718.         FOR x = 1 TO 10
  719.             READ colors(x, ColorSet)
  720.         NEXT x
  721.     NEXT ColorSet
  722.  
  723. END SUB
  724.  
  725. REM $STATIC
  726. ' B-LINK - BASIC Link to the NEWTON
  727. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  728. '
  729. ' This program may be freely distributed provided it is not altered and
  730. ' no fees may be charged for it's distribution.
  731. '
  732. SUB InitSF
  733.  
  734.         COMM$ = "COM1:"
  735.  
  736.         CRLF$ = CHR$(13) + CHR$(10)
  737.         ETX$ = CHR$(3)
  738.         SUB$ = CHR$(26)
  739.         HT$ = CHR$(9)
  740.        
  741. '       this struct defines info about each sharp app
  742.         SharpRec(NNAMES).Sname = "Business Card"
  743.         SharpRec(NNAMES).Sapp = "BUSINESS1  "
  744.         SharpRec(NNAMES).Snum = "1E00"
  745.         SharpRec(NNAMES).Schksum = 1234
  746.         SharpRec(NNAMES).Sfields = 7
  747.  
  748.         ScreenData(NNAMES).fieldptr = 1
  749.         ScreenData(NNAMES).fname = "Names File Data Entry Screen"
  750.  
  751. '       this struct defines info about each data item
  752.         fields(1).SFScreen = NNAMES
  753.         fields(1).SFName = "Last Name:"
  754.         fields(1).SFMax = 30
  755.         fields(1).SFRow = 6
  756.         fields(1).SFCol = 23
  757.         fields(1).SFData = ""
  758.         fields(1).SFedit = " "
  759.         fields(1).SFPos = 5
  760.         fields(1).SFSuff = 1
  761.  
  762.         fields(2).SFScreen = NNAMES
  763.         fields(2).SFName = "Company:"
  764.         fields(2).SFMax = 30
  765.         fields(2).SFRow = 8
  766.         fields(2).SFCol = 23
  767.         fields(2).SFData = ""
  768.         fields(2).SFedit = " "
  769.         fields(2).SFPos = 1
  770.         fields(2).SFSuff = 2
  771.  
  772.         fields(3).SFScreen = NNAMES
  773.         fields(3).SFName = "Title:"
  774.         fields(3).SFMax = 30
  775.         fields(3).SFRow = 10
  776.         fields(3).SFCol = 23
  777.         fields(3).SFData = ""
  778.         fields(3).SFedit = "D"
  779.         fields(3).SFPos = 6
  780.         fields(3).SFSuff = 1
  781.  
  782.         fields(4).SFScreen = NNAMES
  783.         fields(4).SFName = "Address:"
  784.         fields(4).SFMax = 30
  785.         fields(4).SFRow = 12
  786.         fields(4).SFCol = 23
  787.         fields(4).SFData = ""
  788.         fields(4).SFedit = "D"
  789.         fields(4).SFPos = 4
  790.         fields(4).SFSuff = 1
  791.  
  792.         fields(5).SFScreen = NNAMES
  793.         fields(5).SFName = "Phone:"
  794.         fields(5).SFMax = 20
  795.         fields(5).SFRow = 14
  796.         fields(5).SFCol = 23
  797.         fields(5).SFData = ""
  798.         fields(5).SFedit = "D"
  799.         fields(5).SFPos = 2
  800.         fields(5).SFSuff = 1
  801.  
  802.         fields(6).SFScreen = NNAMES
  803.         fields(6).SFName = "Fax:"
  804.         fields(6).SFMax = 20
  805.         fields(6).SFRow = 16
  806.         fields(6).SFCol = 23
  807.         fields(6).SFData = ""
  808.         fields(6).SFedit = "D"
  809.         fields(6).SFPos = 3
  810.         fields(6).SFSuff = 1
  811.  
  812.         fields(7).SFScreen = NNAMES
  813.         fields(7).SFName = "Phone:"
  814.         fields(7).SFMax = 20
  815.         fields(7).SFRow = 18
  816.         fields(7).SFCol = 23
  817.         fields(7).SFData = ""
  818.         fields(7).SFedit = "D"
  819.         fields(7).SFPos = 7
  820.         fields(7).SFSuff = 5
  821.       
  822. ' schedule item
  823.        
  824.         SharpRec(NSCHED).Sname = "Schedule     "
  825.         SharpRec(NSCHED).Sapp = "SCHEDULE1  "
  826.         SharpRec(NSCHED).Snum = "0110"
  827.         SharpRec(NSCHED).Schksum = 1183
  828.         SharpRec(NSCHED).Sfields = 6
  829.  
  830.         ScreenData(NSCHED).fieldptr = 8
  831.         ScreenData(NSCHED).fname = "Single Appointment Data Entry Screen"
  832.        
  833.         fields(8).SFScreen = NSCHED
  834.         fields(8).SFName = "Year:"
  835.         fields(8).SFMax = 4
  836.         fields(8).SFRow = 7
  837.         fields(8).SFCol = 31
  838.         fields(8).SFData = ""
  839.         fields(8).SFedit = "Y"
  840.         fields(8).SFPos = 1
  841.         fields(8).SFSuff = 0
  842.  
  843.         fields(9).SFScreen = NSCHED
  844.         fields(9).SFName = "Start Date (MMDD):"
  845.         fields(9).SFMax = 4
  846.         fields(9).SFRow = 9
  847.         fields(9).SFCol = 31
  848.         fields(9).SFData = ""
  849.         fields(9).SFedit = "M"
  850.         fields(9).SFPos = 2
  851.         fields(9).SFSuff = 0
  852.                 
  853.         fields(10).SFScreen = NSCHED
  854.         fields(10).SFName = "Start Time (HHMM):"
  855.         fields(10).SFMax = 4
  856.         fields(10).SFRow = 9
  857.         fields(10).SFCol = 58
  858.         fields(10).SFData = ""
  859.         fields(10).SFedit = "T"
  860.         fields(10).SFPos = 3
  861.         fields(10).SFSuff = 0
  862.  
  863.         fields(11).SFScreen = NSCHED
  864.         fields(11).SFName = "End Time (HHMM):"
  865.         fields(11).SFMax = 4
  866.         fields(11).SFRow = 10
  867.         fields(11).SFCol = 58
  868.         fields(11).SFData = ""
  869.         fields(11).SFedit = "T"
  870.         fields(11).SFPos = 4
  871.         fields(11).SFSuff = 0
  872.                  
  873.         fields(12).SFScreen = NSCHED
  874.         fields(12).SFName = "Alarm Time (HHMM):"
  875.         fields(12).SFMax = 4
  876.         fields(12).SFRow = 12
  877.         fields(12).SFCol = 58
  878.         fields(12).SFData = ""
  879.         fields(12).SFedit = "T"
  880.         fields(12).SFPos = 5
  881.         fields(12).SFSuff = 1
  882.                 
  883.         fields(13).SFScreen = NSCHED
  884.         fields(13).SFName = "Description:"
  885.         fields(13).SFMax = 25
  886.         fields(13).SFRow = 14
  887.         fields(13).SFCol = 31
  888.         fields(13).SFData = ""
  889.         fields(13).SFedit = " "
  890.         fields(13).SFPos = 6
  891.         fields(13).SFSuff = 0
  892.               
  893. ' anniversary
  894.        
  895.         SharpRec(NANN).Sname = "Anniversary 1"
  896.         SharpRec(NANN).Sapp = "ANN     1  "
  897.         SharpRec(NANN).Snum = "0110"
  898.         SharpRec(NANN).Schksum = 975
  899.         SharpRec(NANN).Sfields = 2
  900.  
  901.         ScreenData(NANN).fieldptr = 14
  902.         ScreenData(NANN).fname = "Recurring Anniversary Data Entry Screen"
  903.  
  904.         fields(14).SFScreen = NANN
  905.         fields(14).SFName = "Date (MMDD):"
  906.         fields(14).SFMax = 4
  907.         fields(14).SFRow = 9
  908.         fields(14).SFCol = 31
  909.         fields(14).SFData = ""
  910.         fields(14).SFedit = "M"
  911.         fields(14).SFPos = 1
  912.         fields(14).SFSuff = 1
  913.  
  914.         fields(15).SFScreen = NANN
  915.         fields(15).SFName = "Description:"
  916.         fields(15).SFMax = 25
  917.         fields(15).SFRow = 11
  918.         fields(15).SFCol = 31
  919.         fields(15).SFData = ""
  920.         fields(15).SFedit = " "
  921.         fields(15).SFPos = 2
  922.         fields(15).SFSuff = 0
  923.               
  924. ' daily note
  925.        
  926.         SharpRec(NDAILY).Sname = "Period       "
  927.         SharpRec(NDAILY).Sapp = "PERIOD  1  "
  928.         SharpRec(NDAILY).Snum = "0110"
  929.         SharpRec(NDAILY).Schksum = 1109
  930.         SharpRec(NDAILY).Sfields = 5
  931.  
  932.         ScreenData(NDAILY).fieldptr = 16
  933.         ScreenData(NDAILY).fname = "Recurring Daily Note Data Entry Screen"
  934.       
  935.         fields(16).SFScreen = NDAILY
  936.         fields(16).SFName = "Start Year (YYYY):"
  937.         fields(16).SFMax = 4
  938.         fields(16).SFRow = 7
  939.         fields(16).SFCol = 31
  940.         fields(16).SFData = ""
  941.         fields(16).SFedit = "Y"
  942.         fields(16).SFPos = 1
  943.         fields(16).SFSuff = 0
  944.  
  945.         fields(17).SFScreen = NDAILY
  946.         fields(17).SFName = "Start Date (MMDD):"
  947.         fields(17).SFMax = 4
  948.         fields(17).SFRow = 9
  949.         fields(17).SFCol = 31
  950.         fields(17).SFData = ""
  951.         fields(17).SFedit = "M"
  952.         fields(17).SFPos = 2
  953.         fields(17).SFSuff = 0
  954.        
  955.         fields(18).SFScreen = NDAILY
  956.         fields(18).SFName = "End Year (YYYY):"
  957.         fields(18).SFMax = 4
  958.         fields(18).SFRow = 7
  959.         fields(18).SFCol = 58
  960.         fields(18).SFData = ""
  961.         fields(18).SFedit = "Y"
  962.         fields(18).SFPos = 3
  963.         fields(18).SFSuff = 0
  964.  
  965.         fields(19).SFScreen = NDAILY
  966.         fields(19).SFName = "End Date (MMDD):"
  967.         fields(19).SFMax = 4
  968.         fields(19).SFRow = 9
  969.         fields(19).SFCol = 58
  970.         fields(19).SFData = ""
  971.         fields(19).SFedit = "M"
  972.         fields(19).SFPos = 4
  973.         fields(19).SFSuff = 1
  974.  
  975.         fields(20).SFScreen = NDAILY
  976.         fields(20).SFName = "Description:"
  977.         fields(20).SFMax = 25
  978.         fields(20).SFRow = 11
  979.         fields(20).SFCol = 31
  980.         fields(20).SFData = ""
  981.         fields(20).SFedit = " "
  982.         fields(20).SFPos = 5
  983.         fields(20).SFSuff = 0
  984.  
  985. ' daily alarm
  986.        
  987.         SharpRec(NALARM).Sname = "Alarm        "
  988.         SharpRec(NALARM).Sapp = "D ALARM 1  "
  989.         SharpRec(NALARM).Snum = "0110"
  990.         SharpRec(NALARM).Schksum = 1091
  991.         SharpRec(NALARM).Sfields = 1
  992.  
  993.         ScreenData(NALARM).fieldptr = 21
  994.         ScreenData(NALARM).fname = "Recurring Daily Alarm Data Entry Screen"
  995.      
  996.         fields(21).SFScreen = NALARM
  997.         fields(21).SFName = "Time (HHMM):"
  998.         fields(21).SFMax = 4
  999.         fields(21).SFRow = 11
  1000.         fields(21).SFCol = 31
  1001.         fields(21).SFData = ""
  1002.         fields(21).SFedit = "T"
  1003.         fields(21).SFPos = 1
  1004.         fields(21).SFSuff = 0
  1005.  
  1006. ' notepad
  1007.       
  1008.         SharpRec(NNOTE).Sname = "Memo         "
  1009.         SharpRec(NNOTE).Sapp = "MEMO    1  "
  1010.         SharpRec(NNOTE).Snum = "0300"
  1011.         SharpRec(NNOTE).Schksum = 1025
  1012.         SharpRec(NNOTE).Sfields = 5
  1013.  
  1014.         ScreenData(NNOTE).fieldptr = 22
  1015.         ScreenData(NNOTE).fname = "NotePad Data Entry Screen"
  1016.     
  1017.         fields(22).SFScreen = NNOTE
  1018.         fields(22).SFName = "Line 1 :"
  1019.         fields(22).SFMax = 30
  1020.         fields(22).SFRow = 7
  1021.         fields(22).SFCol = 31
  1022.         fields(22).SFData = ""
  1023.         fields(22).SFedit = " "
  1024.         fields(22).SFPos = 1
  1025.         fields(22).SFSuff = 0
  1026.  
  1027.         fields(23).SFScreen = NNOTE
  1028.         fields(23).SFName = "Line 2 :"
  1029.         fields(23).SFMax = 30
  1030.         fields(23).SFRow = 8
  1031.         fields(23).SFCol = 31
  1032.         fields(23).SFData = ""
  1033.         fields(23).SFedit = "D"
  1034.         fields(23).SFPos = 2
  1035.         fields(23).SFSuff = 0
  1036.        
  1037.         fields(24).SFScreen = NNOTE
  1038.         fields(24).SFName = "Line 3 :"
  1039.         fields(24).SFMax = 30
  1040.         fields(24).SFRow = 9
  1041.         fields(24).SFCol = 31
  1042.         fields(24).SFData = ""
  1043.         fields(24).SFedit = "D"
  1044.         fields(24).SFPos = 3
  1045.         fields(24).SFSuff = 0
  1046.  
  1047.         fields(25).SFScreen = NNOTE
  1048.         fields(25).SFName = "Line 4 :"
  1049.         fields(25).SFMax = 30
  1050.         fields(25).SFRow = 10
  1051.         fields(25).SFCol = 31
  1052.         fields(25).SFData = ""
  1053.         fields(25).SFedit = "D"
  1054.         fields(25).SFPos = 4
  1055.         fields(25).SFSuff = 0
  1056.  
  1057.         fields(26).SFScreen = NNOTE
  1058.         fields(26).SFName = "Line 5 :"
  1059.         fields(26).SFMax = 30
  1060.         fields(26).SFRow = 11
  1061.         fields(26).SFCol = 31
  1062.         fields(26).SFData = ""
  1063.         fields(26).SFedit = "D"
  1064.         fields(26).SFPos = 5
  1065.         fields(26).SFSuff = 0
  1066.                  
  1067.  
  1068.         fields(27).SFScreen = 99 'end of fields marker
  1069.       
  1070.        
  1071. END SUB
  1072.  
  1073. REM $DYNAMIC
  1074. 'Intro:
  1075. '  Display introduction screen.
  1076. SUB Intro
  1077.     SCREEN 0
  1078.     WIDTH 80, 25
  1079.     COLOR 7, 0
  1080.     CLS
  1081.     COLOR 3
  1082.     center 8, "B - L I N K  V1.0"
  1083.     COLOR 15
  1084.     center 12, "N E W T O N  <-> P C  BASIC LINKUP"
  1085.     COLOR 7
  1086.     center 24, "(c) 1994 by John Marman - All Rights Reserved"
  1087.     COLOR 4
  1088.     center 20, "Press any key if you have backed up your NEWTON..."
  1089.  
  1090.     SparklePause
  1091. END SUB
  1092.  
  1093. REM $STATIC
  1094. ' B-LINK - BASIC Link to the NEWTON
  1095. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  1096. '
  1097. ' This program may be freely distributed provided it is not altered and
  1098. ' no fees may be charged for it's distribution.
  1099. '
  1100. '
  1101. '  Keyboard editor, recognizes Escape,
  1102. '  If first key pressed is an edit key the old string is edited
  1103. '  otherwise, the old string is discarded
  1104. '
  1105. SUB KbdEdit (buffer$, maxlen, fg, bg, cancel, edit$)
  1106.  
  1107.    row = CSRLIN               'Save cursor position
  1108.    col = POS(0)
  1109.  
  1110.    'Remove trailing spaces or uninitialized 0's
  1111.    IF LEFT$(buffer$, 1) = CHR$(0) THEN buffer$ = ""
  1112.    buffer$ = RTRIM$(buffer$)
  1113.    k = INSTR(buffer$, CHR$(0))
  1114.    IF k > 0 THEN buffer$ = LEFT$(buffer$, k - 1) ELSE buffer$ = LEFT$(buffer$, maxlen)
  1115.   
  1116.    LOCATE row, col, 1         'Display string in inverse video
  1117.    COLOR fg, bg
  1118.    PRINT STRING$(maxlen, CHR$(&HF9));
  1119.    LOCATE row, col
  1120.    COLOR bg, fg
  1121.    PRINT buffer$;
  1122.    LOCATE row, col
  1123.    COLOR fg, bg
  1124.   
  1125.    a$ = GetKey$               'Get a key
  1126.  
  1127.    'If the key was a edit key, we will edit the original string
  1128.    'otherwise, we assume the user's typing a new string and the
  1129.    'original is discarded
  1130.    IF a$ >= " " AND a$ <= "~" THEN
  1131.       temp$ = ""
  1132.    ELSE
  1133.       temp$ = buffer$
  1134.    END IF
  1135.    posn = LEN(temp$)
  1136.  
  1137.    done = 0                   '0 until <Esc> or <Enter> is pressed
  1138.    first = 1                  'Indicates first time through
  1139.  
  1140.    DO
  1141.       'Don't read a new key if it's our first time through
  1142.       IF first = 1 THEN
  1143.          first = 0
  1144.       ELSE
  1145.          LOCATE row, col
  1146.          PRINT temp$; STRING$(maxlen - LEN(temp$), CHR$(&HF9))
  1147.          LOCATE row, col + posn
  1148.          a$ = GetKey$
  1149.       END IF
  1150.       SELECT CASE a$
  1151.          CASE "0" TO "9"
  1152.             IF LEN(temp$) < maxlen THEN
  1153.                first$ = LEFT$(temp$, posn)
  1154.                last$ = RIGHT$(temp$, LEN(temp$) - posn)
  1155.                temp$ = first$ + a$ + last$
  1156.                posn = posn + 1
  1157.             ELSE
  1158.                CALL ErrBeep
  1159.             END IF
  1160.          CASE " " TO "~"
  1161.             IF (edit$ = " " OR edit$ = "D") AND LEN(temp$) < maxlen THEN
  1162.                first$ = LEFT$(temp$, posn)
  1163.                last$ = RIGHT$(temp$, LEN(temp$) - posn)
  1164.                temp$ = first$ + a$ + last$
  1165.                posn = posn + 1
  1166.             ELSE
  1167.                CALL ErrBeep
  1168.             END IF
  1169.          CASE CHR$(8)               'Backspace
  1170.             IF posn > 0 THEN
  1171.                first$ = LEFT$(temp$, posn - 1)
  1172.                last$ = RIGHT$(temp$, LEN(temp$) - posn)
  1173.                temp$ = first$ + last$
  1174.                posn = posn - 1
  1175.             ELSE
  1176.                CALL ErrBeep
  1177.             END IF
  1178.          CASE CHR$(0) + CHR$(&H53)  'Delete
  1179.             IF posn < LEN(temp$) THEN
  1180.                first$ = LEFT$(temp$, posn)
  1181.                last$ = RIGHT$(temp$, LEN(temp$) - (posn + 1))
  1182.                temp$ = first$ + last$
  1183.             ELSE
  1184.                CALL ErrBeep
  1185.             END IF
  1186.          CASE CHR$(0) + CHR$(&H4B)  'Left
  1187.             IF posn > 0 THEN
  1188.                posn = posn - 1
  1189.             ELSE
  1190.                CALL ErrBeep
  1191.             END IF
  1192.          CASE CHR$(0) + CHR$(&H4D)  'Right
  1193.             IF posn < LEN(temp$) THEN
  1194.                posn = posn + 1
  1195.             ELSE
  1196.                CALL ErrBeep
  1197.             END IF
  1198.          CASE CHR$(0) + CHR$(&H47)  'Home
  1199.             posn = 0
  1200.          CASE CHR$(0) + CHR$(&H4F)  'End
  1201.             posn = LEN(temp$)
  1202.          CASE CHR$(13)              'Enter (Accept)
  1203.             IF CheckEdit(temp$, edit$) = 1 THEN
  1204.               buffer$ = temp$
  1205.               done = 1
  1206.               cancel = 0
  1207.             ELSE CALL ErrBeep
  1208.             END IF
  1209.          CASE CHR$(27)              'Escape (Cancel)
  1210.             done = 1
  1211.             cancel = 1
  1212.          CASE CHR$(&H0) + CHR$(&H44)   'F10 (Exit)
  1213.             done = 1
  1214.             cancel = 1
  1215.          CASE ELSE
  1216.             CALL ErrBeep
  1217.       END SELECT
  1218.  
  1219.    LOOP UNTIL done
  1220.   
  1221.    COLOR fg, bg                     'Display the resulting string
  1222.    LOCATE row, col, 0
  1223.    PRINT buffer$; SPACE$(maxlen - LEN(buffer$))
  1224.  
  1225. END SUB
  1226.  
  1227. REM $DYNAMIC
  1228. 'LCenter:
  1229. '  Center TEXT$ on the line printer
  1230. SUB LCenter (text$)
  1231.     LPRINT TAB(41 - LEN(text$) / 2); text$
  1232. END SUB
  1233.  
  1234. REM $STATIC
  1235. '
  1236. ' Loads a database from disk
  1237. '
  1238. SUB LoadRecords
  1239.  
  1240.    IF NumRecords > 0 THEN
  1241.      IF GetYesNo("Erase existing records in memory [Y/N]?") = 0 THEN EXIT SUB
  1242.      END IF
  1243.  
  1244.    CALL ShowMessage("Loading records...")
  1245.  
  1246.    'Open data file
  1247.    OPEN "B-LINK.DAT" FOR RANDOM AS #1 LEN = LEN(CRrecords(0))
  1248.  
  1249.    'Calculate numRecords and allocate records array
  1250.    NumRecords = LOF(1) \ LEN(CRrecords(0))
  1251.    REDIM CRrecords(NumRecords) AS CRrecord
  1252.  
  1253.    'Read records
  1254.    FOR i = 1 TO NumRecords
  1255.       GET #1, i, CRrecords(i)
  1256.    NEXT i
  1257.    CLOSE #1
  1258.  
  1259.    IF NumRecords > 0 THEN CurrRecord = 1
  1260.    CALL ClearMessage
  1261.    
  1262.     Box 9, 19, 14, 61
  1263.     center 11, "B-LINK File Import:"
  1264.     center 12, "Number of records read in:" + STR$(NumRecords)
  1265.  
  1266.     SLEEP 0
  1267.  
  1268. END SUB
  1269.  
  1270. REM $DYNAMIC
  1271. 'Menu:
  1272. '  Handles Menu Selection for a single menu (either sub menu, or menu bar)
  1273. '  currChoiceX  :  Number of current choice
  1274. '  maxChoice    :  Number of choices in the list
  1275. '  choice$()    :  Array with the text of the choices
  1276. '  itemRow()    :  Array with the row of the choices
  1277. '  itemCol()    :  Array with the col of the choices
  1278. '  menuhelp$()      :  Array with the help text for each choice
  1279. '  barMode      :  Boolean:  TRUE = menu bar style, FALSE = drop down style
  1280. '
  1281. '  Returns the number of the choice that was made by changing currChoiceX
  1282. '  and returns the scan code of the key that was pressed to exit
  1283. '
  1284. FUNCTION Menu (CurrChoiceX, MaxChoice, choice$(), ItemRow(), ItemCol(), menuHelp$(), BarMode)
  1285.    
  1286.     currChoice = CurrChoiceX
  1287.  
  1288.     'if in bar mode, color in menu bar, else color box/shadow
  1289.     'bar mode means you are currently in the menu bar, not a sub menu
  1290.     IF BarMode THEN
  1291.         COLOR colors(7, ColorPref), colors(4, ColorPref)
  1292.         LOCATE 1, 1
  1293.         PRINT SPACE$(80);
  1294.     ELSE
  1295.         FancyCls colors(2, ColorPref), colors(1, ColorPref)
  1296.         COLOR colors(7, ColorPref), colors(4, ColorPref)
  1297.         Box ItemRow(1) - 1, ItemCol(1) - 1, ItemRow(MaxChoice) + 1, ItemCol(1) + LEN(choice$(1)) + 1
  1298.         
  1299.         COLOR colors(10, ColorPref), colors(6, ColorPref)
  1300.         FOR a = 1 TO MaxChoice + 1
  1301.             LOCATE ItemRow(1) + a - 1, ItemCol(1) + LEN(choice$(1)) + 2
  1302.             PRINT CHR$(178); CHR$(178);
  1303.         NEXT a
  1304.         LOCATE ItemRow(MaxChoice) + 2, ItemCol(MaxChoice) + 2
  1305.         PRINT STRING$(LEN(choice$(MaxChoice)) + 2, 178);
  1306.     END IF
  1307.     
  1308.     'print the choices
  1309.     COLOR colors(7, ColorPref), colors(4, ColorPref)
  1310.     FOR a = 1 TO MaxChoice
  1311.         LOCATE ItemRow(a), ItemCol(a)
  1312.         PRINT choice$(a);
  1313.     NEXT a
  1314.  
  1315.     finished = FALSE
  1316.  
  1317.     WHILE NOT finished
  1318.         
  1319.         GOSUB MenuShowCursor
  1320.         GOSUB MenuGetKey
  1321.         GOSUB MenuHideCursor
  1322.  
  1323.         SELECT CASE Kbd$
  1324.             CASE CHR$(0) + "H": GOSUB MenuUp
  1325.             CASE CHR$(0) + "P": GOSUB MenuDown
  1326.             CASE CHR$(0) + "K": GOSUB MenuLeft
  1327.             CASE CHR$(0) + "M": GOSUB MenuRight
  1328.             CASE CHR$(13): GOSUB MenuEnter
  1329.             CASE CHR$(27): GOSUB MenuEscape
  1330.             CASE ELSE:  BEEP
  1331.         END SELECT
  1332.     WEND
  1333.  
  1334.     Menu = currChoice
  1335.  
  1336.     EXIT FUNCTION
  1337.  
  1338.  
  1339. MenuEnter:
  1340.     finished = TRUE
  1341.     RETURN
  1342.  
  1343. MenuEscape:
  1344.     currChoice = 0
  1345.     finished = TRUE
  1346.     RETURN
  1347.  
  1348. MenuUp:
  1349.     IF BarMode THEN
  1350.         BEEP
  1351.     ELSE
  1352.         currChoice = (currChoice + MaxChoice - 2) MOD MaxChoice + 1
  1353.     END IF
  1354.     RETURN
  1355.  
  1356. MenuLeft:
  1357.     IF BarMode THEN
  1358.         currChoice = (currChoice + MaxChoice - 2) MOD MaxChoice + 1
  1359.     ELSE
  1360.         currChoice = -2
  1361.         finished = TRUE
  1362.     END IF
  1363.     RETURN
  1364.  
  1365. MenuRight:
  1366.     IF BarMode THEN
  1367.         currChoice = (currChoice) MOD MaxChoice + 1
  1368.     ELSE
  1369.         currChoice = -3
  1370.         finished = TRUE
  1371.     END IF
  1372.     RETURN
  1373.  
  1374. MenuDown:
  1375.     IF BarMode THEN
  1376.         finished = TRUE
  1377.     ELSE
  1378.         currChoice = (currChoice) MOD MaxChoice + 1
  1379.     END IF
  1380.     RETURN
  1381.  
  1382. MenuShowCursor:
  1383.     COLOR colors(8, ColorPref), colors(9, ColorPref)
  1384.     LOCATE ItemRow(currChoice), ItemCol(currChoice)
  1385.     PRINT choice$(currChoice);
  1386.     PrintHelpLine menuHelp$(currChoice)
  1387.     RETURN
  1388.  
  1389. MenuGetKey:
  1390.     Kbd$ = ""
  1391.     WHILE Kbd$ = ""
  1392.         Kbd$ = INKEY$
  1393.     WEND
  1394.     RETURN
  1395.  
  1396. MenuHideCursor:
  1397.     COLOR colors(7, ColorPref), colors(4, ColorPref)
  1398.     LOCATE ItemRow(currChoice), ItemCol(currChoice)
  1399.     PRINT choice$(currChoice);
  1400.     RETURN
  1401.  
  1402.  
  1403. END FUNCTION
  1404.  
  1405. ' B-LINK - BASIC Link to the NEWTON
  1406. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  1407. '
  1408. ' This program may be freely distributed provided it is not altered and
  1409. ' no fees may be charged for it's distribution.
  1410. '
  1411. 'MenuSystem:
  1412. '  Main routine that controls the program.  Uses the MENU function
  1413. '  to implement menu system and calls the appropriate function to handle
  1414. '  the user's selection
  1415. SUB MenuSystem
  1416.  
  1417.     DIM choice$(20), menuRow(20), menuCol(20), menuHelp$(20)
  1418.     LOCATE , , 0
  1419.     choice = 1
  1420.     finished = FALSE
  1421.  
  1422.     ColorPref = 2
  1423.  
  1424.     WHILE NOT finished
  1425.         GOSUB MenuSystemMain
  1426.  
  1427.         subchoice = -1
  1428.         WHILE subchoice < 0
  1429.             SELECT CASE choice
  1430.                 CASE 1: GOSUB MenuSystemFile
  1431.                 CASE 2: GOSUB MenuSystemNewton
  1432.                 CASE 3: GOSUB MenuSystemComm
  1433.             END SELECT
  1434.             FancyCls colors(2, ColorPref), colors(1, ColorPref)
  1435.  
  1436.             SELECT CASE subchoice
  1437.                 CASE -2: choice = (choice + 4) MOD 3 + 1
  1438.                 CASE -3: choice = (choice) MOD 3 + 1
  1439.             END SELECT
  1440.         WEND
  1441.     WEND
  1442.     EXIT SUB
  1443.  
  1444.  
  1445. MenuSystemMain:
  1446.     FancyCls colors(2, ColorPref), colors(1, ColorPref)
  1447.     COLOR colors(7, ColorPref), colors(4, ColorPref)
  1448.     Box 9, 19, 14, 61
  1449.     center 11, "Use arrow keys to navigate menu system"
  1450.     center 12, "Press Enter to select a menu item"
  1451.  
  1452.     choice$(1) = " File "
  1453.     choice$(2) = " Newton "
  1454.     choice$(3) = " Port   "
  1455.  
  1456.     menuRow(1) = 1: menuCol(1) = 2
  1457.     menuRow(2) = 1: menuCol(2) = 15
  1458.     menuRow(3) = 1: menuCol(3) = 28
  1459.     
  1460.     menuHelp$(1) = "Load/Save a database file or quit B-LINK"
  1461.     menuHelp$(2) = "Add data in NEWTON format"
  1462.     menuHelp$(3) = "Change the current COM port"
  1463.     
  1464.     DO
  1465.         NewChoice = Menu((choice), 3, choice$(), menuRow(), menuCol(), menuHelp$(), TRUE)
  1466.     LOOP WHILE NewChoice = 0
  1467.     choice = NewChoice
  1468.     RETURN
  1469.  
  1470. MenuSystemFile:
  1471.    
  1472.     choice$(1) = " Load   "
  1473.     choice$(2) = " Save   "
  1474.     choice$(3) = " Import "
  1475.     choice$(4) = " Summary"
  1476.     choice$(5) = " Exit   "
  1477.  
  1478.     menuRow(1) = 3: menuCol(1) = 2
  1479.     menuRow(2) = 4: menuCol(2) = 2
  1480.     menuRow(3) = 5: menuCol(3) = 2
  1481.     menuRow(4) = 6: menuCol(4) = 2
  1482.     menuRow(5) = 7: menuCol(5) = 2
  1483.  
  1484.     menuHelp$(1) = "Load existing B-LINK file"
  1485.     menuHelp$(2) = "Save current B-LINK file"
  1486.     menuHelp$(3) = "Import Data - to be developed!"
  1487.     menuHelp$(4) = "Summary of Data"
  1488.     menuHelp$(5) = "Exit the B-LINK"
  1489.  
  1490.     subchoice = Menu(1, 5, choice$(), menuRow(), menuCol(), menuHelp$(), FALSE)
  1491.  
  1492.     SELECT CASE subchoice
  1493.         CASE 1: CALL LoadRecords
  1494.         CASE 2: CALL SaveRecords
  1495.         CASE 4: CALL Summary
  1496.         CASE 5: finished = TRUE
  1497.         CASE ELSE
  1498.     END SELECT
  1499.     RETURN
  1500.  
  1501. MenuSystemNewton:
  1502.     
  1503.     choice$(1) = " Business Card "
  1504.     choice$(2) = " Appointment   "
  1505.     choice$(3) = " Notepad       "
  1506.     choice$(4) = " Anniversary   "
  1507.     choice$(5) = " Daily Note    "
  1508.     choice$(6) = " Daily Alarm   "
  1509.  
  1510.     menuRow(1) = 3: menuCol(1) = 15
  1511.     menuRow(2) = 4: menuCol(2) = 15
  1512.     menuRow(3) = 5: menuCol(3) = 15
  1513.     menuRow(4) = 6: menuCol(4) = 15
  1514.     menuRow(5) = 7: menuCol(5) = 15
  1515.     menuRow(6) = 8: menuCol(6) = 15
  1516.                                 
  1517.     menuHelp$(1) = "Add a business card"
  1518.     menuHelp$(2) = "Add a single appointment to the schedule"
  1519.     menuHelp$(3) = "Add a notepad item"
  1520.     menuHelp$(4) = "Create a recurring annual calendar note"
  1521.     menuHelp$(5) = "Create a recurring daily note"
  1522.     menuHelp$(6) = "Create a recurring daily alarm"
  1523.    
  1524.     subchoice = Menu(1, 6, choice$(), menuRow(), menuCol(), menuHelp$(), FALSE)
  1525.  
  1526.     SELECT CASE subchoice
  1527.         CASE 1 'business card
  1528.            SFScreenNum = NNAMES
  1529.            CALL DataEntry
  1530.         CASE 2 'appointment
  1531.            SFScreenNum = NSCHED
  1532.            CALL DataEntry
  1533.         CASE 3 'notepad
  1534.           SFScreenNum = NNOTE
  1535.           CALL DataEntry
  1536.         CASE 4 'anniversary
  1537.           SFScreenNum = NANN
  1538.           CALL DataEntry
  1539.         CASE 5 'daily note
  1540.           SFScreenNum = NDAILY
  1541.           CALL DataEntry
  1542.         CASE 6 'alarm
  1543.           SFScreenNum = NALARM
  1544.           CALL DataEntry
  1545.         CASE ELSE
  1546.     END SELECT
  1547.     RETURN
  1548.  
  1549. MenuSystemComm:
  1550.    
  1551.     choice$(1) = " COM1 "
  1552.     choice$(2) = " COM2 "
  1553.  
  1554.     menuRow(1) = 3: menuCol(1) = 28
  1555.     menuRow(2) = 4: menuCol(2) = 28
  1556.                                
  1557.     menuHelp$(1) = "Set COMM port to COM1:"
  1558.     menuHelp$(2) = "Set COMM port to COM2:"
  1559.   
  1560.     subchoice = Menu(1, 2, choice$(), menuRow(), menuCol(), menuHelp$(), FALSE)
  1561.  
  1562.     SELECT CASE subchoice
  1563.         CASE 1 'com1
  1564.            COMM$ = "COM1:"
  1565.         CASE 2 'com2
  1566.            COMM$ = "COM2:"
  1567.         CASE ELSE
  1568.     END SELECT
  1569.     RETURN
  1570.  
  1571. END SUB
  1572.  
  1573. REM $STATIC
  1574. '
  1575. ' Makes the next record the current record
  1576. '
  1577. SUB NextRecord
  1578.  
  1579.    i = 1
  1580.    WHILE CurrRecord + i <= NumRecords
  1581.         IF CRrecords(CurrRecord + i).CRType = SFScreenNum THEN GOTO foundnext
  1582.         i = i + 1
  1583.         WEND
  1584.    CALL ErrBeep
  1585.    EXIT SUB
  1586.  
  1587. foundnext:
  1588.    CurrRecord = CurrRecord + i
  1589.    CALL ShowRecord
  1590.  
  1591. END SUB
  1592.  
  1593. '
  1594. ' Creates the main display and calls ShowRecord
  1595. '
  1596. SUB PaintDisplay
  1597.  
  1598.    COLOR scrnFg, scrnBg, scrnBg        'Clear screen
  1599.    CLS
  1600.  
  1601.    COLOR statFg, statBg                'Create title status bar
  1602.    LOCATE 1, 1: PRINT SPACE$(80)
  1603.    center 1, ScreenData(SFScreenNum).fname
  1604.  
  1605.    COLOR winFg, winBg                  'Create record window
  1606.    CALL Frame(WINTOP, WINBOTTOM, WINLEFT, WINRIGHT)
  1607.  
  1608.         i = ScreenData(SFScreenNum).fieldptr
  1609.         DO WHILE fields(i).SFScreen = SFScreenNum
  1610.                 LOCATE fields(i).SFRow, fields(i).SFCol - (INSTR(fields(i).SFName, ":") + 1)
  1611.                 PRINT fields(i).SFName
  1612.                 i = i + 1
  1613.         LOOP
  1614.    
  1615.  
  1616.    LOCATE 25, 1                        'Display function-key bar
  1617.    COLOR scrnFg, scrnBg: PRINT "1";
  1618.    COLOR statFg, statBg: PRINT "Help  ";
  1619.    COLOR scrnFg, scrnBg: PRINT " 2";
  1620.    COLOR statFg, statBg: PRINT "Add   ";
  1621.    COLOR scrnFg, scrnBg: PRINT " 3";
  1622.    COLOR statFg, statBg: PRINT "Delete";
  1623.    COLOR scrnFg, scrnBg: PRINT " 4";
  1624.    COLOR statFg, statBg: PRINT "Edit  ";
  1625.    COLOR scrnFg, scrnBg: PRINT " 5";
  1626.    COLOR statFg, statBg: PRINT "Find  ";
  1627.    COLOR scrnFg, scrnBg: PRINT " 6";
  1628.    COLOR statFg, statBg: PRINT "Prev  ";
  1629.    COLOR scrnFg, scrnBg: PRINT " 7";
  1630.    COLOR statFg, statBg: PRINT "Next  ";
  1631.    COLOR scrnFg, scrnBg: PRINT " 8";
  1632.    COLOR statFg, statBg: PRINT "Send  ";
  1633.    COLOR scrnFg, scrnBg: PRINT " 9";
  1634.    COLOR statFg, statBg: PRINT "Print ";
  1635.    COLOR scrnFg, scrnBg: PRINT " 10";
  1636.    COLOR statFg, statBg: PRINT "Exit  ";
  1637.  
  1638.    CALL ShowRecord                     'Display current record
  1639.  
  1640. END SUB
  1641.  
  1642. '
  1643. ' Makes the previous record the current record
  1644. '
  1645. SUB PrevRecord
  1646.  
  1647.    i = 1
  1648.    WHILE CurrRecord - i > 0
  1649.         IF CRrecords(CurrRecord - i).CRType = SFScreenNum THEN GOTO foundprev
  1650.         i = i + 1
  1651.         WEND
  1652.    CALL ErrBeep
  1653.    EXIT SUB
  1654.  
  1655. foundprev:
  1656.    CurrRecord = CurrRecord - i
  1657.    CALL ShowRecord
  1658.  
  1659. END SUB
  1660.  
  1661. REM $DYNAMIC
  1662. 'PrintHelpLine:
  1663. '  Prints help text on the bottom row in the proper color
  1664. SUB PrintHelpLine (menuHelp$)
  1665.     COLOR colors(5, ColorPref), colors(4, ColorPref)
  1666.     LOCATE 25, 1
  1667.     PRINT SPACE$(80);
  1668.     center 25, menuHelp$
  1669. END SUB
  1670.  
  1671. REM $STATIC
  1672. '
  1673. ' Send the database to the printer
  1674. '
  1675. SUB PrintRecords
  1676.    IF GetYesNo("Send records to printer [Y/N]?") THEN
  1677.       CALL ShowMessage("Printing records...")
  1678.       FOR j = 1 TO NumRecords
  1679. '       loop until end of this record type - move along pos pointer
  1680.         IF CRrecords(j).CRType < S THEN S = 1
  1681.         recpos = 1
  1682.         i = ScreenData(SFScreenNum).fieldptr
  1683.         LPRINT : LPRINT "------Record# "; j; " ------"
  1684.         DO WHILE fields(i).SFScreen = CRrecords(j).CRType
  1685.                 fields(i).SFData = MID$(CRrecords(j).CRData, recpos, fields(i).SFMax)
  1686.                 recpos = recpos + fields(i).SFMax
  1687.                 LPRINT LEFT$(fields(i).SFName, INSTR(fields(i).SFName, ":") + 1); LEFT$(fields(i).SFData, fields(i).SFMax)
  1688.                 i = i + 1
  1689.                 LOOP
  1690.         LPRINT
  1691.       NEXT j
  1692.       CALL ClearMessage
  1693.    END IF
  1694.  
  1695. END SUB
  1696.  
  1697. '
  1698. ' Writes the database to disk
  1699. '
  1700. SUB SaveRecords
  1701.  
  1702.    IF GetYesNo("Save records to disk [Y/N]?") THEN
  1703.       CALL ShowMessage("Saving records...")
  1704.       KILL "B-LINK.DAT"
  1705.  
  1706.       'Open the data file
  1707.       OPEN "B-LINK.DAT" FOR RANDOM AS #1 LEN = LEN(CRrecords(0))
  1708.  
  1709.       'Write the records to disk
  1710.       FOR i = 1 TO NumRecords
  1711.          PUT #1, i, CRrecords(i)
  1712.       NEXT i
  1713.       CLOSE #1
  1714.  
  1715.       CALL ClearMessage
  1716.    END IF
  1717.  
  1718. END SUB
  1719.  
  1720. REM $DYNAMIC
  1721. ' B-LINK - BASIC Link to the NEWTON
  1722. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  1723. '
  1724. ' This program may be freely distributed provided it is not altered and
  1725. ' no fees may be charged for it's distribution.
  1726. '
  1727. SUB showdump (dinp$, dLEN)
  1728. FOR i = 1 TO dLEN
  1729.         char$ = MID$(dinp$, i, 1)
  1730.         IF char$ < " " THEN PRINT "<"; ASC(char$); ">";  ELSE PRINT char$;
  1731.         NEXT i
  1732. END SUB
  1733.  
  1734. REM $STATIC
  1735. '
  1736. ' Displays the given message in the message area
  1737. '
  1738. SUB ShowMessage (message$)
  1739.  
  1740.    COLOR scrnFg, scrnBg
  1741.    LOCATE MESSAGEROW, (80 - LEN(message$)) / 2    'Center message string
  1742.    PRINT message$
  1743.  
  1744. END SUB
  1745.  
  1746. ' B-LINK - BASIC Link to the NEWTON
  1747. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  1748. '
  1749. ' This program may be freely distributed provided it is not altered and
  1750. ' no fees may be charged for it's distribution.
  1751. '
  1752. '
  1753. ' Displays the current record
  1754. '
  1755. SUB ShowRecord
  1756.  
  1757.    COLOR winFg, winBg
  1758.   
  1759.    'Show current record number against number of records
  1760.    LOCATE WINTOP, WINLEFT + 5
  1761.    PRINT "["; CurrRecord; "/"; NumRecords; "]"; STRING$(10, &HCD)
  1762.  
  1763.    IF NumRecords = 0 OR CRrecords(CurrRecord).CRType <> SFScreenNum THEN
  1764.       CALL ClearFields
  1765.    ELSE
  1766.         i = ScreenData(SFScreenNum).fieldptr
  1767.         recpos = 1
  1768.         DO WHILE fields(i).SFScreen = SFScreenNum
  1769.                 fields(i).SFData = MID$(CRrecords(CurrRecord).CRData, recpos, fields(i).SFMax)
  1770.                 recpos = recpos + fields(i).SFMax
  1771.                 LOCATE fields(i).SFRow, fields(i).SFCol
  1772.                 PRINT LEFT$(fields(i).SFData, fields(i).SFMax)
  1773.                 i = i + 1
  1774.                 LOOP
  1775.    END IF
  1776.  
  1777. END SUB
  1778.  
  1779. '
  1780. ' Uses a shell sort to sort all the records in the database.
  1781. ' Records are compared by calling CompareRecords.
  1782. '
  1783. SUB SortRecords
  1784.  
  1785.    IF NumRecords = 0 THEN        'Nothing to sort
  1786.       CALL ErrBeep
  1787.       EXIT SUB
  1788.    END IF
  1789.  
  1790.    IF GetYesNo("Sort records [Y/N]?") THEN
  1791.  
  1792.       'Set comparison offset to half the number of records
  1793.       offset = NumRecords \ 2
  1794.  
  1795.       DO WHILE offset > 0        'Loop until offset gets to 0
  1796.          limit = NumRecords - offset
  1797.          DO
  1798.             switch = 0           'Assume no switches at this offset
  1799.  
  1800.             'Compare elements and switch those out of order
  1801.             FOR i = 1 TO limit
  1802.                IF CompareRecords(i, i + offset) THEN
  1803.                   SWAP CRrecords(i), CRrecords(i + offset)
  1804.                   switch = i
  1805.                END IF
  1806.             NEXT i
  1807.  
  1808.             'Sort on next pass only to where last switch was made
  1809.             limit = switch - offset
  1810.          LOOP WHILE switch
  1811.  
  1812.          'No switches at last offset, try one half as big
  1813.          offset = offset \ 2
  1814.  
  1815.       LOOP
  1816.       CurrRecord = 1             'Go to first record and update screen
  1817.       CALL ShowRecord
  1818.    END IF
  1819.  
  1820. END SUB
  1821.  
  1822. REM $DYNAMIC
  1823. '  Creates a fancy border
  1824. SUB SparklePause
  1825.  
  1826.     COLOR 4, 0
  1827.     a$ = "*    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    "
  1828.     WHILE INKEY$ <> "": WEND 'empty type ahead
  1829.     WHILE INKEY$ = ""
  1830.         FOR a = 1 TO 5
  1831.             LOCATE 1, 1: PRINT MID$(a$, a, 80); : LOCATE 22, 1: PRINT MID$(a$, 6 - a, 80);
  1832.             FOR b = 2 TO 21
  1833.                 c = (a + b) MOD 5
  1834.                 IF c = 1 THEN
  1835.                     LOCATE b, 80: PRINT "*"; : LOCATE 23 - b, 1: PRINT "*";
  1836.                 ELSE
  1837.                     LOCATE b, 80: PRINT " "; : LOCATE 23 - b, 1: PRINT " ";
  1838.                 END IF
  1839.             NEXT b
  1840.         NEXT a
  1841.     WEND
  1842. END SUB
  1843.  
  1844. REM $STATIC
  1845. SUB Summary
  1846. DIM count(6)
  1847.  
  1848.         FOR i = 1 TO NumRecords
  1849.                 j = CRrecords(i).CRType
  1850.                 count(j) = count(j) + 1
  1851.                 NEXT i
  1852.  
  1853.         Box 9, 19, 21, 61
  1854.         center 10, "** B-LINK V1.0 **"
  1855.         LOCATE 12, 22: PRINT " Business Card "; count(NNAMES)
  1856.         LOCATE 13, 22: PRINT " Appointment   "; count(NSCHED)
  1857.         LOCATE 14, 22: PRINT " Notepad       "; count(NNOTE)
  1858.         LOCATE 14, 45: PRINT " Port: "; COMM$
  1859.         LOCATE 15, 22: PRINT " Anniversary   "; count(NANN)
  1860.         LOCATE 16, 22: PRINT " Daily Note    "; count(NDAILY)
  1861.         LOCATE 17, 22: PRINT " Daily Alarm   "; count(NALARM)
  1862.         LOCATE 18, 22: PRINT " TOTAL........."; NumRecords
  1863.         LOCATE 20, 30: PRINT "(c) 1994 John Marman"
  1864.         SLEEP 0
  1865. END SUB
  1866.  
  1867. REM $DYNAMIC
  1868. 'Trim$:
  1869. '  Remove null and spaces from the end of a string.
  1870. FUNCTION Trim$ (x$)
  1871.  
  1872.     IF x$ = "" THEN
  1873.         Trim$ = ""
  1874.     ELSE
  1875.         lastChar = 0
  1876.         FOR a = 1 TO LEN(x$)
  1877.             y$ = MID$(x$, a, 1)
  1878.             IF y$ <> CHR$(0) AND y$ <> " " THEN
  1879.                 lastChar = a
  1880.             END IF
  1881.         NEXT a
  1882.         Trim$ = LEFT$(x$, lastChar)
  1883.     END IF
  1884.     
  1885. END FUNCTION
  1886.  
  1887. REM $STATIC
  1888. ' B-LINK - BASIC Link to the NEWTON
  1889. ' FREEWARE by John Marman (Compuserve: 70410,1257)
  1890. '
  1891. ' This program may be freely distributed provided it is not altered and
  1892. ' no fees may be charged for it's distribution.
  1893. '
  1894. FUNCTION XmitNewton%
  1895. DIM outdata$(7)
  1896.        
  1897.         IF GetYesNo("Press 'Y' if you have saved your data!") = 0 THEN EXIT FUNCTION
  1898.         IF GetYesNo("Press 'Y' if you have selected '" + SharpRec(CRrecords(CurrRecord).CRType).Sname + "' from the SHARP icon") = 0 THEN EXIT FUNCTION
  1899.            
  1900.         CALL ShowMessage("Opening port: " + COMM$ + " and preparing data...")
  1901.  
  1902. '       open the serial port with options to allow it to talk to the NEWTON
  1903.         OPEN COMM$ + "9600,N,8,1,cd0,cs0,ds0,rs,bin" FOR RANDOM AS #2
  1904.  
  1905.         APPNAME$ = SharpRec(CRrecords(CurrRecord).CRType).Sapp
  1906.         APPNUM$ = SharpRec(CRrecords(CurrRecord).CRType).Snum
  1907.       
  1908. '       extract data from CurrRecord
  1909.         i = ScreenData(SFScreenNum).fieldptr
  1910.         recpos = 1
  1911.         DO WHILE fields(i).SFScreen = SFScreenNum
  1912.                 temp$ = MID$(CRrecords(CurrRecord).CRData, recpos, fields(i).SFMax)
  1913.                 k = INSTR(temp$, CHR$(0))
  1914.                 IF k > 0 THEN temp$ = LEFT$(temp$, k - 1) ELSE temp$ = LEFT$(temp$, fields(i).SFMax)
  1915.                 ' embed a newline at the end of each note line
  1916.                 IF SFScreenNum = NNOTE AND fields(i).SFPos < 5 AND LEN(temp$) > 0 THEN temp$ = temp$ + HT$
  1917.                 FOR j = 1 TO fields(i).SFSuff
  1918.                         temp$ = temp$ + CRLF$
  1919.                         NEXT j
  1920.                 outdata$(fields(i).SFPos) = temp$
  1921.                 recpos = recpos + fields(i).SFMax
  1922.                 i = i + 1
  1923.                 LOOP
  1924.  
  1925. '       rearrange the data into the proper order for the NEWT
  1926.         appdata$ = ""
  1927.         FOR i = 1 TO SharpRec(CRrecords(CurrRecord).CRType).Sfields
  1928.                 appdata$ = appdata$ + outdata$(i)
  1929.                 NEXT i
  1930.  
  1931. '       calculate the correct checksum
  1932.         outbuf$ = APPNUM$ + "00" + CRLF$ + APPNAME$ + CRLF$ + "00" + appdata$ + CRLF$ + SUB$
  1933.         chksum = checksum(appdata$) + SharpRec(CRrecords(CurrRecord).CRType).Schksum
  1934.         chksum$ = ComposeChkSum(chksum)
  1935.  
  1936.         IF GetYesNo("Press 'Y' then press 'RECEIVE' on your NEWTON") = 0 THEN EXIT FUNCTION
  1937.         CALL ShowMessage("Transmitting...")
  1938.  
  1939. '       look for the NEWT
  1940.  
  1941.                             '*** NOTE:
  1942.         INP$ = INPUT$(2, 2) '*** IF YOU GET STUCK HERE IT'S PROBABLY
  1943.                             '*** BECAUSE YOU HAVE NOT SELECTED THE
  1944.                             '*** CORRECT COM PORT! (THE PORT'S NOT
  1945.                             '*** RESPONDING)
  1946.  
  1947.         IF INP$ <> ETX$ + "D" THEN GOTO errx
  1948.  
  1949. '       tell the NEWT that we're a SHARP 8200
  1950.          PRINT #2, "8200" + CRLF$ + "0000" + HT$ + "0000" + HT$ + "01000000" + HT$ + CRLF$ + SUB$ + "4D03" + CRLF$ + SUB$;
  1951.  
  1952. '       look for confirmation, and see what app is selected on the NEWT
  1953.        
  1954.         INP$ = INPUT$(44, 2) ' *** IF YOU GET STUCK HERE IT'S PROBABLY
  1955.                              ' *** BECAUSE THE COM PORT HAS SCREWED UP!
  1956.                              ' *** TRY RESTARTING THE DOS SESSION AND RE-TRY
  1957.        
  1958.         IF RIGHT$(INP$, 13) <> APPNAME$ + CRLF$ THEN GOTO errx
  1959.  
  1960. '       ok... send the data
  1961.         PRINT #2, ETX$ + "0000" + HT$ + "0000" + HT$ + "01000000" + HT$ + CRLF$;
  1962.         PRINT #2, outbuf$;
  1963.         PRINT #2, chksum$ + CRLF$ + SUB$;
  1964.  
  1965. '       success!
  1966.         CLOSE #2
  1967.         XmitNewton = 0
  1968.         CALL ClearMessage
  1969.         IF GetYesNo("Success! Delete the current record (Y/N)") <> 0 THEN CALL DeleteRecord
  1970.         EXIT FUNCTION
  1971.  
  1972. errx:
  1973.         CLOSE #2
  1974.         CLS
  1975.         PRINT "Error transmitting information!"
  1976.         PRINT "Port="; COMM$; "  Appname="; APPNAME$
  1977.         PRINT : PRINT "Outbuf :";
  1978.         CALL showdump(outbuf$, LEN(outbuf$))
  1979.         PRINT : PRINT : PRINT "Inbuf :";
  1980.         CALL showdump(INP$, LEN(INP$))
  1981.         PRINT : PRINT : PRINT
  1982.         PRINT "The COMM may be screwed up... select QUIT and try again!"
  1983.         PRINT
  1984.         IF GetYesNo("Press 'Y' to continue, 'N' to QUIT") = 0 THEN SYSTEM
  1985.         XmitNewton = -1
  1986.  
  1987. END FUNCTION
  1988.  
  1989.